var express = require('express');
var router = express.Router();
var moment = require('moment')
var fs = require('fs')
var request = require('request')
var http = require('http');
const multer = require('multer');
const crypto = require('crypto')
const db = require('../sql/connect')
const jwt = require('jsonwebtoken')
const mysql = require('mysql');
const BASE64 = "base64";
const NodeRSA = require("node-rsa");
const SECRET = 'asdasfas#$@!%!%!!AWE'


const getuser = async (req, res, next) => {
    const raw = String(req.headers.authorization).split(' ').pop()
    const { username } = jwt.verify(raw, SECRET)
    res.username = username
    next()
}
// const verifySign = async (req, res, next) => {
//     let sql = "select pubkey from useritem where username = ?"
//     db.base(sql, res.username, (response) => {
//         if (response.type === 1) {
//             var publicKey = new NodeRSA({ b: 512 })
//             publicKey.importKey(response.results[0].pubkey)
//             var result = publicKey.verify(Buffer.from(req.body.random), req.body.signedData, 'Buffer', BASE64);
//             res.signResult = result
//             console.log(res.signResult)
//         } else {
//             res.signResult = false
//         }
//     })
//     next()
// }

router.post('/', getuser, async (req, res) => {
    let sql = 'select * from useritem where username = ?';
    db.base(sql, res.username, (response) => {
        if (response.results.length === 1) {
            res.json({
                "type": "success",
                "content": response.results[0]
            })
        } else {
            res.json({
                "type": "error",
                "content": "错误token"
            })
        }
    })
});

router.post('/send', getuser, async (req, res, next) => {
    console.log(req.body)
    var JsonTemp = req.body
    var str = "" + req.body.fileid + req.body.filename + req.body.access + req.body.validity
    let sql = 'select pubkey from useritem where username = ?'
    db.base(sql, res.username, (response) => {
        console.log(response)
        if (response.type === 1 && response.results.length === 1) {
            var publicKey = new NodeRSA({ b: 512 })
            publicKey.importKey(response.results[0].pubkey)

            var result = publicKey.verify(Buffer.from(str), req.body.signedData, 'Buffer', BASE64);
            console.log(result)
            if (result === true) {
                sql = 'select owner from fileitem where fileid = ?'
                db.base(sql, req.body.fileid, (response) => {
                    console.log(response)
                    if (response.type === 1 && response.results.length === 1) {
                        let sql = 'INSERT INTO message SET ?'
                        //消息中添加权限请求者信息
                        JsonTemp.requester = res.username
                        //消息中添加文件拥有者信息
                        JsonTemp.owner = String(response.results[0].owner)
                        //消息中添加发送时间
                        JsonTemp.timestamp = moment(Date.now()).format('YYYY-MM-DD HH:mm:ss')
                        JsonTemp.signedData = req.body.signedData
                        let messageInfo = {
                            sender: res.username,
                            receiver: JsonTemp.owner,
                            content: JSON.stringify(JsonTemp),
                            timestamp: JsonTemp.timestamp,
                            state: "已发送"
                        }
                        db.base(sql, messageInfo, (response) => {
                            console.log(response)
                            if (response.type == 0) {
                                res.json({
                                    "type": "error",
                                    "content": "发送失败"
                                })
                            } else {
                                console.log("log--更新消息表成功--"+Date.now)
                                res.json({
                                    "type": "success",
                                    "content": "发送成功"
                                })
                            }
                        })
                    } else {
                        res.json({
                            "type": "error",
                            "content": "发送失败"
                        })
                    }

                })
            } else {
                res.json({
                    "type": "error",
                    "content": "发送失败"
                })
            }
        }
    })

})

router.post('/getMessage', getuser, async (req, res, next) => {
    let sql = 'select messageID,content,state from message where receiver = ?';
    //标志字段为sender时查找用户发送的
    if (req.body.type == 'sender') {
        sql = 'select messageID,content,state from message where sender = ?';
    }
    db.base(sql, res.username, (response) => {
        if (response.type === 0) {
            res.json({
                "type": "error",
                "content": "查找失败"
            })
        } else {
            response.results.forEach(function (value, i) {
                JsonTemp = JSON.parse(value.content)
                JsonTemp.state = response.results[i].state
                JsonTemp.messageID = value.messageID
                response.results[i] = JsonTemp
            });
            res.json({
                "type": "success",
                "content": response.results
            })
            {
                // response.results.forEach(function (value, i) {
                //     let sql = 'select originalname from fileitem where fileid = ?';
                //     db.base(sql, JSON.parse(value.content).fileid, (resp) => {

                //         if (resp.type === 1 && resp.results.length > 0) {
                //             response.results[i].filename = resp.results[0].originalname
                //             response.results[i].access = JSON.parse(response.results[0].content).access
                //             // delete response.results[i].content
                //             if (response.results.length - 1 === i) {
                //                 // response.results.forEach(function(value,i){
                //                 //     delete response.results[i].content
                //                 // })
                //                 res.json({
                //                     "type": "success",
                //                     "content": response.results
                //                 })
                //             }
                //         } else {
                //             res.json({
                //                 "type": "error",
                //                 "content": resp.results
                //             })
                //         }
                //     })
                // });
            }
        }
    })
})

router.post('/create', async (req, res, next) => {
    let sql = "insert into blockchain set ?"
    var timestamp = moment(Date.now()).format('YYYY-MM-DD HH:mm:ss')
    let data = {
        prehash: 'e50e6bc797e7b9e7474223fbb64c9175608ef1caa73b398d81aeaa0b9c779824',
        hash: 'b626b0a491893addef0c400076f3e1e65a8409e8f14e101881454a2e1ae99a05',
        timestamp: timestamp,
        agreement: JSON.stringify({
            name: "shouquan",
            content: "I'm the founder"
        })
    }
    db.base(sql, data, (response) => {
        if (response.type == 0) {
            res.json({
                "type": "error",
                "content": "创世失败"
            })
        } else {
            console.log("log--同步创世区块成功--"+Date.now)
            res.json({
                "type": "success",
                "content": "创世成功"
            })
        }
    })
})

router.post('/operation', getuser, async (req, res, next) => {
    let sql = "select * from message where messageID = ?"
    db.base(sql, req.body.messageID, (response) => {
        if (response.type === 1) {
            //判断是否重复执行
            if (response.results[0].state === req.body.state) {
                res.json({
                    "type": "error",
                    "content": "禁止重复执行"
                })
            } else {
                sql = 'select pubkey from useritem where username = ?'
                db.base(sql, res.username, (response) => {
                    if (response.type === 1 && response.results.length === 1) {
                        var publicKey = new NodeRSA({ b: 512 })
                        publicKey.importKey(response.results[0].pubkey)
                        var result = publicKey.verify(Buffer.from(req.body.random), req.body.signedData, 'Buffer', BASE64);
                        if (result === true) {
                            var prehash = ''
                            var preheight = 0
                            var message = ''
                            //准备要写入区块链的数据 
                            //获取前一区块哈希和高度
                            sql = 'select hash,height FROM blockchain ORDER BY height DESC LIMIT 0,1 ;'
                            db.base(sql, null, (response) => {
                                if (response.type === 0) {
                                    res.json({
                                        "type": "error",
                                        "content": "执行失败"
                                    })
                                } else {
                                    prehash = response.results[0].hash
                                    preheight = response.results[0].height
                                    //高度加一
                                    preheight += 1
                                    //获取权限消息
                                    let sql = 'select receiver,sender,content from message where messageID = ?'
                                    db.base(sql, req.body.messageID, (response) => {
                                        if (response.type === 0) {
                                            res.json({
                                                "type": "error",
                                                "content": "执行失败"
                                            })
                                        } else {
                                            message = response.results[0]
                                            //获取时间戳并计算当前区块hash
                                            var timestamp = moment(Date.now()).format('YYYY-MM-DD HH:mm:ss')
                                            var hash = crypto.createHash('SHA256').update(preheight + prehash + timestamp).digest('hex')
                                            //广播哈希
                                            //写入区块链
                                            let sql = 'insert into blockchain set ?'
                                            var JSONTEMP = JSON.parse(message.content)
                                            if (req.body.state != "accept") {
                                                JSONTEMP.access = "权限已收回"

                                            }
                                            let blockdata = {
                                                prehash: prehash,
                                                hash: hash,
                                                timestamp: timestamp,
                                                // usernamea: message.sender,
                                                // usernameb: message.receiver,
                                                agreement: JSON.stringify(JSONTEMP)
                                            }
                                            if(req.body.flag ===1){blockdata = req.body.blockdata}
                                            db.base(sql, blockdata, (response) => {
                                                if (response.type == 0) {
                                                    res.json({
                                                        "type": "error",
                                                        "content": "执行失败"
                                                    })
                                                } else {
                                                    //权限记录写入permtable表
                                                    let sql = 'DELETE FROM permtable where requester = ? and receiver  = ? and fileid = ?'
                                                    let permtableData = [message.sender, message.receiver, JSON.parse(message.content).fileid]
                                                    db.base(sql, permtableData, (response) => {
                                                        if (response.type === 1) {
                                                            sql = 'insert into permtable set ?'
                                                            permtableData = {
                                                                requester: message.sender,
                                                                receiver: message.receiver,
                                                                fileid: JSON.parse(message.content).fileid,
                                                                blockheight: preheight
                                                            }
                                                            db.base(sql, permtableData, (response) => {
                                                                if (response.type == 0) {
                                                                    res.json({
                                                                        "type": "error",
                                                                        "content": "执行失败"
                                                                    })
                                                                } else {
                                                                    let sql = 'update message set state = ? where messageID = ?;';
                                                                    let data = [req.body.state, req.body.messageID]
                                                                    db.base(sql, data, (response) => {
                                                                        if (response.type == 0) {
                                                                            res.json({
                                                                                "type": "error",
                                                                                "content": "执行失败"
                                                                            })
                                                                        } else {
                                                                            req.body.blockdata = blockdata
                                                                            req.body.flag = 1
                                                                            //broadcast.broadcastToAll(req,urlList,"/home/operation")
                                                                            console.log("log--更新区块链信息成功--")
                                                                            console.log("log--区块信息为--\n"+blockdata.timestamp +"\n"+blockdata.prehash+"\n"+blockdata.hash+blockdata.agreement)
                                                                            res.json({
                                                                                "type": "success",
                                                                                "content": "执行成功"
                                                                            })
                                                                        }
                                                                    })

                                                                }
                                                            })


                                                        } else {
                                                            console.log(error)
                                                        }
                                                    })

                                                }
                                            })
                                        }
                                    })
                                }
                            })

                        } else {
                            res.json({
                                "type": "error",
                                "content": "执行失败"
                            })
                        }
                    }
                })
            }
        } else {
            res.json({
                "type": "error",
                "content": "执行失败"
            })
        }
    })
})
//收回权限
router.post('/takeBackAccess', getuser, function (req, res, next) {
    let sql = 'select messageID from message where sender = ?  and receiver = ? and  timestamp = ?'
    db.base(sql, [req.body.requester, req.body.owner, req.body.timestamp], (response) => {
        var url = "http://127.0.0.1:3000/home/operation"
        var requestData = {
            state: "refuse",
            messageID: response.results[0].messageID,
            random: req.body.random,
            signedData: req.body.signedData
        }
        request({
            url: url,
            method: "POST",
            json: true,
            headers: {
                "content-type": "application/json",
                "Authorization": "token " + req.headers.authorization
            },
            body: requestData
        }, function (error, response, body) {
            if (!error && response.statusCode == 200) {
                res.json(body)
                console.log("log--收回权限成功--"+Date.now)
            }
        });

        // httprequest(url,requestData);

        // function httprequest(url,data){
        //     request({
        //         url: url,
        //         method: "POST",
        //         json: true,
        //         headers: {
        //             "content-type": "application/json",
        //         },
        //         body: requestData
        //     }, function(error, response, body) {
        //         if (!error && response.statusCode == 200) {
        //             console.log(body) // 请求成功的处理逻辑
        //         }
        //     });
        // };



        // //转发 post 请求
        // var path = "/home/operation";
        // var content = req.body;
        // _fn.postData('127.0.0.1', 3000, path, content, function (data) {
        //     res.send(data);
        // });
        // console.log(req.body)
    })
})


//上传文件
router.post('/uploadfile', getuser, multer({ dest: 'upload' }).array('file', 10), async (req, res, next) => {
    //上传文件
    if (req.files === undefined) {
        res.send("错误");
        return
    }
    if (req.files.length > 10) {
        res.send('文件数量过多')
        return
    } else {
        let fileInfos = []
        dateTemp = moment(Date.now()).format('YYYY-MM-DD HH:mm:ss')
        for (var i in req.files) {
            let file = req.files[i];
            let fileInfo = []

            //获取文件基本信息,为数据库记录做准备
            fileInfo[0] = file.originalname;
            fileInfo[1] = res.username;
            fileInfo[2] = file.path;
            fileInfo[3] = dateTemp

            fileInfos.push(fileInfo)
        }
        //信息记录入数据库
        let sql = 'INSERT INTO fileitem (`originalname`, `owner`, `filepath`,`timestamp`) VALUES ?;'
        db.base(sql, [fileInfos], (response) => {
            if (response.type == 0) {
                res.json({
                    "type": "error",
                    "content": "执行失败"
                })
                return
            } res.json({
                "type": "success",
                "content": "执行成功"
            })
        })

    }

})

router.post('/uploadfileInfo',getuser,async(req,res,next)=>{
    //信息记录入数据库
    let sql = 'INSERT INTO fileitem (`originalname`, `owner`, `filepath`,`timestamp`) VALUES ?;'
    db.base(sql, req.body, (response) => {
        if (response.type == 0) {
            console.log("log--更新文件信息失败--"+Date.now)
            res.json({
                "type": "error",
                "content": "执行失败"
            })
            return
        }else{
            console.log("log--更新文件信息成功--"+Date.now)
            res.json({
            "type": "success",
            "content": "执行成功"
        })}
    })
})

//获取文件信息
router.post('/getfileinfo', getuser, async (req, res, next) => {
    let sql = 'select * from fileitem where owner = ?'
    db.base(sql, res.username, (response) => {
        if (response.type == 1) {
            //查找成功
            res.json({
                "type": "success",
                "content": response.results
            })
        } else {
            //查找失败
        }
    })
})

//获取文件信息
router.post('/getallfileinfo', getuser, async (req, res, next) => { 
    let sql = 'select * from fileitem'
    db.base(sql, res.username, (response) => {
        if (response.type == 1) {
            //查找成功
            res.json({
                "type": "success",
                "content": response.results
            })
        } else {
            //查找失败
        }
    })
})

//删除文件
router.post('/deleteFile', getuser, async (req, res, next) => {
    let sql = "select pubkey from useritem where username = ?"
    db.base(sql, res.username, (response) => {
        if (response.type === 1) {
            var publicKey = new NodeRSA({ b: 512 })
            publicKey.importKey(response.results[0].pubkey)
            var result = publicKey.verify(Buffer.from(req.body.random), req.body.signedData, 'Buffer', BASE64);
            if (result === true) {
                let sql = 'select filepath from fileitem where fileid = ?'
                db.base(sql, req.body.fileid, (response) => {
                    if (response.type === 1) {
                        console.log(response.results[0])
                        //fs.unlinkSync(response.results[0].filepath)
                        let sql = 'DELETE FROM permtable WHERE fileid = ?'
                        db.base(sql, req.body.fileid, (response) => {
                            if(response.type != 1){
                                console.log("log--删除文件权限出错--"+Date.now)
                            }
                        })
                        sql = 'DELETE FROM fileitem WHERE fileid = ?'
                        db.base(sql, req.body.fileid, (response) => {
                            if (response.type === 1) {
                                console.log("log--更新文件权限成功--"+Date.now)
                                res.json({
                                    "type": "success",
                                    "content": "操作成功"
                                })
                            }

                        })
                    }
                })
            } else {
                res.json({
                    "type": "error",
                    "content": "操作失败"
                })
            }


        } else {
            res.signResult = false
        }
    })
})

//获取权限信息
router.post('/getaccess', getuser, async (req, res, next) => {
    //结合权限表从区块链中查找协议信息获取权限
    let sql = "select agreement from permtable inner join blockchain on permtable.blockheight = blockchain.height where requester = ?"
    //默认查找给出去的数据
    if (req.body.type == 'receiver') {
        sql = "select agreement from permtable inner join blockchain on permtable.blockheight = blockchain.height where receiver = ?"
    }
    db.base(sql, res.username, (response) => {
        if (response.type === 1) {
            response.results.forEach(function (value, i) {
                response.results[i] = JSON.parse(value.agreement)
            });
            res.json({
                "type": "success",
                "content": response.results
            })
        }

    })


})

//响应其他节点获取权限信息的请求
router.post('/getfileAccess', getuser, async (req, res, next) => {
    let sql = 'select agreement from blockchain where height = ?'
    db.base(sql, req.body.blockheight, (response) => {
        if (response.type === 1) {
            //判断权限
            var str = String(JSON.parse(response.results[0].agreement).access)
            if (str.indexOf("r") != -1) {
                //拥有权限
                console.log("log--响应权限请求成功，有权限--"+Date.now)
                res.json({
                    "type": "success",
                    "content": '拥有权限'
                })
            } else {
                console.log("log--响应权限请求失败，无权限--"+Date.now)
                res.json({
                    "type": "error",
                    "content": '无权限'
                })
            }
        }
    })
})

//获取文件
router.post('/getfile', getuser, async (req, res, next) => {
    // 第一步 查找请求的文件信息
    let sql = 'select * from fileitem where fileid = ?'
    db.base(sql, req.body.fileid, (response) => {
        if (response.type == 1) {
            // 获取文件拥有者
            // res.owner = response.results.owner
            var fileinfo = response.results[0]
            //第二步 查找文件权限所在区块
            let sql = ' SELECT blockheight FROM permtable where(requester,fileid) = ?;'
            let data = [res.username, req.body.fileid]
            db.base(sql, [[data]], (response) => {
                if (response.type === 1 && response.results.length >= 1) {
                    let sql = 'select agreement from blockchain where height = ?'
                    db.base(sql, response.results[response.results.length - 1].blockheight, (response) => {
                        if (response.type === 1) {
                            //判断权限
                            var str = String(JSON.parse(response.results[0].agreement).access)

                            if (str.indexOf("r") != -1) {
                                //拥有权限
                                //下载文件
                                let path = fileinfo.filepath;
                                let filename = JSON.parse(response.results[0].agreement).filename

                                var load = fs.createReadStream(path); //创建输入流入口
                                res.writeHead(200, {
                                    'Content-Type': 'application/force-download',
                                    'Content-Disposition': 'attachment; filename=' + encodeURI(filename) + '.docx'
                                });
                                load.on('data', (chunk) => {
                                    res.write(chunk, 'binary')
                                });
                                load.on('end', () => {
                                    res.end()
                                })
                                // load.pipe(res);// 通过管道方式写入
                            } else {
                                res.json({
                                    "type": "error",
                                    "content": '下载失败'
                                })
                            }
                        }
                    })
                } else {
                    res.json({
                        "type": "error",
                        "content": '下载失败'
                    })
                    return
                }
            })

        } else {
            res.json({
                "type": "error",
                "content": '下载失败'
            })
        }
    })

    //从区块链中查找权限
    // 1.先查找拥有者给出的所有权限，再从这些信息中查找给出对应文件的权限
    //     for message from response.results(
    //         if(message.usernameb == fileowner){
    //             get message.agreement.filename == 请求文件文件名
    //             返回 message.agreement.权限
    //         }
    //     )
    // //

    // 查找对应存储的区块高度


    //有权限就给，没权限就拒绝

    // 下载文件
    // 第一种方式
    // path = 'upload/3f8bdb210f0ba7ff613f97741f5a5c6e'
    // res.download(path,'res') //直接调用download方法即可
    // 这种方法在调用download改名时候不好使，暂时不用

    //第二种方式
    // let path = 'upload/3f8bdb210f0ba7ff613f97741f5a5c6e';
    // var load = fs.createReadStream(path); //创建输入流入口
    // res.writeHead(200, {
    //     'Content-Type': 'application/force-download',
    //     'Content-Disposition': 'attachment; filename=' + encodeURI(path) + '.docx'
    // });
    // load.pipe(res);// 通过管道方式写入

})


_fn = {
    getData: function (path, callback) {
        http.get({
            hostname: apiHost,
            path: path
        }, function (res) {
            var body = [];
            res.on('data', function (chunk) {
                body.push(chunk);
            });
            res.on('end', function () {
                body = Buffer.concat(body);
                callback(body.toString());
            });
        });
    },
    postData: function (apiHost, port, path, data, callback) {
        data = data || {};
        content = JSON.stringify(data);
        var options = {
            host: apiHost,
            port: port,
            path: path,
            method: 'POST',
            headers: {
                'Content-Type': 'multipart/form-data',
                'Content-Length': content.length
                //根据提交请求类型不同而不同，以上适用多媒体文件
                //可查询各种报头类型代表的意思
            }
        };
        http.request(options, function (res) {
            var _data = '';
            res.on('data', function (chunk) {
                _data += chunk;
            });
            res.on('end', function () {
                callback(_data);
            });
        });
        req.write(content);
        req.end()
    }
};


module.exports = router;    